home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / uclp13.zip / UC.PAS < prev    next >
Pascal/Delphi Source File  |  1992-09-20  |  31KB  |  1,034 lines

  1. Program UC; {UltraClip - a Clipboard Extender}
  2. uses WObjects, WinTypes, WinProcs,Strings,Win31,ClipObj,Buttons,Sclptext;
  3. {$R UC.RES}
  4. {$D UltraClip - Copyright (c) 1992 by Doug Overmyer}
  5. CONST
  6.   AppName : PChar = 'UC';
  7.   FrmName : PChar = 'UC';
  8.   ChdName : PChar = 'UCChd';
  9.   cm_Copy       = cm_EditCopy;     {menuitem EditCopy    }
  10.   cm_Paste      = cm_EditPaste;    {menuitem EditPaste   }
  11.   cm_Delete     = cm_EditDelete;
  12.   cm_Cut        = cm_EditCut;
  13.     um_ButtonU    = 198;
  14.   um_ButtonD    = 199;
  15.   id_But1       = 301;
  16.   id_But2       = 302;
  17.   id_But3       = 303;
  18.   id_But4       = 304;
  19.   id_But5       = 305;
  20.   id_But6       = 306;
  21.   id_ST1        = 401;
  22.   id_D1RB1      = 451;
  23.   id_D1RB2      = 452;
  24.   id_D1EC1      = 453;
  25.   id_D1EC2      = 454;
  26.   id_D1EC3      = 455;
  27.   id_D2LB1      = 461;
  28.   cm_RunCB      = 500;
  29.   cm_AutoPaste  = 501;
  30.   cm_ClipClear  = 502;
  31.   cm_Configure  = 503;
  32.   cm_IconAll    = 504;
  33.   cm_RestoreAll = 505;
  34.   cm_Exit       = 24340;     
  35.   idm_About     = 801;
  36.   idm_ClipBoard = 803;
  37.   id_Timer      = 999;
  38.   um_Copy       = cm_EditCopy;
  39.   um_Delete     = cm_EditDelete;
  40.   um_ChildExit  =  901;
  41.   um_ChildFocus = 902;
  42.   um_GetSelf    = 903;
  43.   id_ChildMenuPos = 2;
  44.   IniFile       = 'UC.INI';
  45. type
  46. TUCApp = object(TApplication)
  47.     procedure InitMainWindow; Virtual;
  48. end;
  49.  
  50. PStrCollectionNS=^TStrCollectionNS;
  51. TStrCollectionNS = object(TStrCollection)
  52.     procedure Insert(Item:Pointer);virtual;
  53. end;
  54.  
  55. type
  56.     TfR = Record
  57.       Strings:PStrCollectionNS;
  58.     Indexes:PMultiSelRec;
  59. end;
  60.  
  61. PUCBtn = ^TUCBtn;
  62. TUCBtn = object(TODButton)
  63.     constructor    Init(AParent:PWindowsObject; AnID:Integer;ATitle:PChar;
  64.       X1,Y1,W1,H1:Integer;IsDefault:Boolean;BMP:PChar;AGroup:PGroupBox);
  65.   procedure WMRButtonDown(var Msg:TMessage);virtual wm_First+wm_RButtonDown;
  66.   procedure WMRButtonUp(var Msg:TMessage);virtual wm_First+wm_RButtonUp;
  67. end;
  68.  
  69. PUCStatic = ^TUCStatic;
  70. TUCStatic = object(TSText)
  71.     constructor Init(AParent:PWindowsObject;AnID:Integer; ATitle:PChar;
  72.       NewX,NewY,NewW,NewH:Integer; NewState,NewStyle:Integer);
  73.     procedure WMRButtonDown(var Msg:TMessage);virtual wm_First+wm_RButtonDown;
  74. end;
  75.  
  76. PUCWin = ^TUCWin;
  77. TUCWin = OBJECT(TMDIWindow)
  78.     BN:Array[0..6] of PUCBtn;
  79.   ST1:PUCStatic;
  80.     NextViewer:HWnd;
  81.   IsAutoPaste:Boolean;
  82.   Help:Array[0..50] of Char;
  83.   Helv:HFont;
  84.   ThumbRect:TRect;
  85.   Grid:TPoint;
  86.     constructor Init(ATitle : PChar; AMenu : HMenu);
  87.   destructor Done; Virtual;
  88.   procedure SetupWindow; Virtual;
  89.   function GetClassName : PChar; Virtual;
  90.   procedure GetWindowClass(var AWndClass: TWndClass);Virtual;
  91.   procedure InitClientWindow; Virtual;
  92.   function  InitChild : PWindowsObject; Virtual;
  93.   procedure DispInfo;
  94.   procedure Paint(PaintDC:HDC;var PaintInfo:TPaintStruct);virtual;
  95.   procedure IDBut1(var Msg:TMessage);virtual id_First+id_But1;
  96.   procedure IDBut2(var Msg:TMessage);virtual id_First+id_But2;
  97.   procedure IDBut3(var Msg:TMessage);virtual id_First+id_But3;
  98.   procedure IDBut4(var Msg:TMessage);virtual id_First+id_But4;
  99.   procedure IDBut5(var Msg:TMessage);virtual id_First+id_But5;
  100.     procedure IDBut6(var Msg:TMessage);virtual id_First+id_But6;
  101.   procedure ODButtonD(var Msg:TMessage);virtual wm_User+um_ButtonD;
  102.   procedure ODButtonU(var Msg:TMessage);virtual wm_User+um_ButtonU;
  103.   procedure RetitleKids;
  104.   procedure CMIconAll(var Msg:TMessage);virtual cm_First+cm_IconAll;
  105.   procedure CMRestoreAll( var Msg:TMessage);virtual cm_First+cm_RestoreAll;
  106.   procedure CMCut(var Msg:TMessage);virtual cm_First+cm_Cut;
  107.   procedure CMCopy(var Msg:TMessage);virtual cm_First+cm_Copy;
  108.   procedure CMPaste(var Msg:TMessage);virtual cm_First+cm_Paste;
  109.   procedure CMDelete(var Msg:TMessage);virtual cm_First+cm_Delete;
  110.     procedure CMAutoPaste(var Msg:TMessage);virtual cm_First+cm_AutoPaste;
  111.   procedure CMClipClear(var Msg:TMessage);virtual cm_First+cm_ClipClear;
  112.   procedure CMRunCB(var Msg:TMessage);virtual cm_First+cm_RunCB;
  113.   procedure CMConfigure(var Msg:TMessage);virtual cm_First+cm_Configure;
  114.   procedure WMChangeCBChain(var Msg:TMessage);virtual wm_First+wm_ChangeCBChain;
  115.   procedure WMDrawClipBoard(var Msg:TMessage);virtual wm_First+wm_DrawClipBoard;
  116.   procedure WMTimer(var Msg:TMessage);virtual wm_First+wm_Timer;
  117.   procedure WMPaletteChanged(var Msg:TMessage);virtual wm_First+wm_PaletteChanged;
  118.   procedure WMQueryNewPalette(var Msg:TMessage);virtual wm_first+wm_QueryNewPalette;
  119.   procedure WMSize(var Msg:TMessage);virtual wm_First+wm_Size;
  120.   procedure    WMDrawItem(var Msg:TMessage);virtual wm_First + wm_DrawItem;
  121.   procedure WMSysCommand(var Msg:TMessage);virtual wm_First+wm_SysCommand;
  122.   procedure WMNCRButtonUp(var Msg:TMessage);virtual wm_First+wm_NCRButtonUp;
  123.   procedure UMChildExit(var Msg:TMessage);virtual wm_User+um_ChildExit;
  124.   procedure UMChildFocus(var Msg:TMessage);virtual wm_User+um_ChildFocus;
  125.   procedure UMRButtonDown(var Msg:TMessage);virtual wm_User+wm_RButtonDown;
  126. end;
  127.  
  128. PUCChild = ^TUCChild;
  129. TUCChild = OBJECT(TWindow)
  130.     CO:PClipObj;
  131.   IsActive:Boolean;
  132.   ThumbRect:TRect;
  133.     constructor Init(AParent:PWindowsObject;ATitle:PChar;SRx:TRect);
  134.   function GetClassName : PChar; Virtual;
  135.   procedure GetWindowClass(var AWndClass: TWndClass);Virtual;
  136.   destructor Done;virtual;
  137.   procedure SetupWindow;virtual;
  138.   procedure Paint(PaintDC:HDC;var PaintInfo:TPaintStruct);virtual;
  139.   procedure WMNCRButtonUp(var Msg:TMessage);virtual wm_First+wm_NCRButtonUp;
  140.   procedure WMPaletteChanged(var Msg:TMessage);virtual wm_First+wm_PaletteChanged;
  141.   procedure WMMDIActivate(var Msg:TMessage);virtual wm_First+wm_MDIActivate;
  142.   procedure WMSize(var Msg:TMessage);virtual wm_First+wm_Size;
  143.   procedure WMRButtonUp(var Msg:TMessage);virtual wm_First+wm_RButtonUp;
  144.   procedure WMLButtonDown(var Msg:TMessage);virtual wm_First+wm_LButtonDown;
  145.   procedure UMGetSelf(var Msg:TMessage);virtual wm_User+um_GetSelf;
  146.   procedure UMCopy(var Msg:TMessage);virtual WM_USER+UM_COPY;
  147.   procedure UMDelete(var Msg:TMessage);virtual WM_USER+UM_DELETE;
  148. end;
  149.  
  150. PUCClient = ^TUCClient;
  151. TUCClient = object(TMDIClient)
  152.     constructor Init(aParent:PMDIWindow);
  153.   procedure WMSize(var Msg:TMessage);virtual WM_First+WM_SIZE;
  154. end;
  155.  
  156. PUCAbout = ^TUCAbout;     {about dialog}
  157. TUCAbout = object(TDialog)
  158.     procedure WMCtlColor(var Msg:TMessage);virtual wm_First+wm_CtlColor;
  159. end;
  160.  
  161. PUCdlg2 = ^TUCDlg2;
  162. TUCDlg2 = object(TDialog)              {clipboard formats dialog}
  163.     constructor Init(AParent: PWindowsObject; AName: PChar);
  164.     procedure SetupWindow; virtual;
  165. end;
  166. { ********************  Functions *********************************}
  167. function StrTok(P:PChar;C:Char):PChar;
  168. const
  169.     Next:Pchar = nil;
  170. begin
  171.     if P = NIL then P := Next;
  172.   if P <> NIL then
  173.       begin
  174.       Next := StrScan(P,C);
  175.       If Next <> NIL then
  176.           begin
  177.         Next^ := #0;
  178.         Next := Next+1;
  179.           end;
  180.       end;
  181.   StrTok := P;
  182. end;
  183. function LongMin(A, B: LongInt): LongInt;
  184. begin
  185.   if A < B then LongMin := A else LongMin := B;
  186. end;
  187.  
  188. function LongMax(A, B: LongInt): LongInt;
  189. begin
  190.   if A > B then LongMax := A else LongMax := B;
  191. end;
  192.  
  193. {***********************  TUCApp  **************************}
  194. procedure TUCApp.InitMainWindow;
  195. begin
  196.   MainWindow := New(PUCWin, Init('UltraClip',LoadMenu(HInstance, 'UC_Menu')));
  197. end;
  198. {***********************  TUCWin  ***********************************}
  199. constructor TUCWin.Init(ATitle : PChar;AMenu : HMenu);
  200. const
  201.     BMP:Array[0..6] of PChar = ('','Btn1','Btn2','Btn3','Btn4','Btn5','Btn6');
  202. var
  203.     Indx:Integer;
  204.   LFont : TLogFont;
  205.   TNS:Integer;
  206. begin
  207.     TMDIWindow.Init(ATitle, AMenu);
  208.   ChildMenuPos := id_ChildMenuPos;
  209.   IsAutoPaste := False;
  210.   NextViewer := 0;
  211.   For Indx := 0 to 6 do BN[Indx] := nil;
  212.     For Indx := 1 to 6 do
  213.       BN[Indx]:=New(PUCBtn,Init(@Self,300+Indx,'',
  214.         Pred(Indx)*32,32,32,32,False,BMP[Indx],nil));
  215.   St1 := New(PUCStatic,Init(@Self,id_St1,'',210,5,250,23,sr_Recessed,
  216.             dt_Left or dt_VCenter or dt_SingleLine));
  217.   IsAutoPaste := Bool(GetPrivateProfileInt(AppName,'AutoPaste',0,INIFILE));
  218.   TNS := GetPrivateProfileInt(AppName,'ThumbNailSize',125,INIFILE);
  219.   Grid.X := GetPrivateProfileInt(AppName,'Across',4,INIFILE);
  220.     Grid.Y := GetPrivateProfileInt(AppName,'Down',2,INIFILE);
  221.   SetRect(ThumbRect,0,0,TNS,TNS);
  222.     StrCopy(Help,'');
  223.   GetObject(GetStockObject(System_Font),sizeof(TLogFont),@LFont);
  224.   StrCopy(LFont.lfFaceName,'Helv');
  225.     LFont.lfHeight := round(LFont.lfHeight * 2 / 3);
  226.   LFont.lfWidth := 0;
  227.   LFont.lfPitchAndFamily := 0;
  228.   Helv := CreateFontIndirect(LFont);
  229. end;
  230.  
  231. procedure TUCWin.SetUpWindow;
  232. var
  233.     GlobMem:LongInt;
  234.   Title:Array[0..25] of Char;
  235.   SysMenu:HMenu;
  236.   Mssg:PChar;
  237.   Msg:TMessage;
  238. begin
  239.   TMDIWindow.SetUpWindow;
  240.   SetTimer(HWindow,id_Timer,5000,nil);
  241.   WMTimer( Msg);
  242.   Mssg := 'Start AutoPaste';
  243.   ModifyMenu(Attr.Menu,cm_AutoPaste,mf_ByCommand+mf_String,
  244.            cm_AutoPaste,Mssg);
  245.   Sysmenu := GetSystemMenu(hWindow,false);
  246.   AppendMenu(SysMenu,MF_Separator,0,nil);
  247.     AppendMenu(Sysmenu,0,idm_About,'About');
  248.   DispInfo;
  249.     St1^.SetFont(Helv);
  250.   if IsAutoPaste then
  251.       begin
  252.     IsAutoPaste := False;
  253.     CMAutoPaste(Msg);
  254.     end;
  255.   RetitleKids;
  256.   IDBut6(Msg);
  257. end;
  258.  
  259. destructor TUCWin.Done;
  260. begin
  261.     if IsAutoPaste then
  262.       if NextViewer > 0 then
  263.     ChangeClipboardChain(HWindow,NextViewer);
  264.   KillTimer(HWindow,id_Timer);
  265.   DeleteObject(Helv);
  266.     TMDIWindow.Done;
  267. end;
  268.  
  269. function TUCWin.GetClassName;
  270. begin
  271.     GetClassName := AppName;
  272. end;
  273.  
  274. procedure TUCWin.GetWindowClass(VAR AWndClass :TWndClass);
  275. begin
  276.   TMDIWindow.GetWindowClass(AWndClass);
  277.   AWndClass.hIcon := LoadIcon(HInstance, 'UC_Icon');
  278. end;
  279.  
  280. procedure TUCWin.InitClientWindow;
  281. begin
  282.   ClientWnd:= New(PUCClient,Init(@Self));
  283.   WITH ClientWnd^.Attr DO
  284.     Style := Style or WS_VScroll or WS_HScroll;
  285. end;
  286.  
  287. function TUCWin.InitChild : PWindowsObject;
  288. begin
  289.   InitChild := New(PUCChild, Init(@Self, 'Baby',ThumbRect));
  290. end;
  291.  
  292. procedure TUCWin.DispInfo;
  293. type
  294.   ORec = Record
  295.       AutoP:PChar;
  296.     Info:PChar;
  297.   end;
  298. var
  299.     ChildWin:HWnd;
  300.     Child:PUCChild;
  301.   Size:LongInt;
  302.   Mssg,Stats:Array[0..100] of Char;
  303.   O    :ORec;
  304. begin
  305.     fillchar(O,sizeOf(ORec),0);Child := nil;ChildWin := 0;
  306.     StrCopy(Stats,'');
  307.   if StrLen(Help) > 0 then
  308.       begin
  309.       St1^.SetText(Help);
  310.     Exit;
  311.     end;
  312.   if IsAutoPaste then
  313.       O.AutoP := 'P'
  314.   else
  315.       O.AutoP := '_';
  316.   ChildWin :=GetTopWindow(ClientWnd^.HWindow);
  317.   if ChildWin <> 0 then
  318.       begin
  319.     Child := PUCChild(GetObjectPtr(ChildWin));
  320.     if Child <> nil then
  321.       if Child^.CO <> nil then
  322.           begin
  323.       Child^.CO^.GetInfo(Stats,sizeof(Stats));
  324.         O.Info := Stats;
  325.       end;
  326.     end;
  327.     wvsprintf(Mssg,'%s  %s',O);
  328.     ST1^.SetText(Mssg);
  329.     InvalidateRect(ST1^.HWindow,nil,false);
  330. end;
  331.  
  332. procedure TUCWin.Paint(PaintDC:HDC;var PaintInfo:TPaintStruct);
  333. var
  334.     ob:HBrush;
  335.   CR:TRect;
  336. begin
  337.     GetClientRect(HWindow,CR);
  338.     ob:=SelectObject(PaintDC,GetStockObject(ltGray_Brush));
  339.     Rectangle(PaintDC,0,0,CR.Right,32);
  340.   SelectObject(PaintDC,ob);
  341. end;
  342.  
  343. procedure TUCWin.IDBut1(var Msg:TMessage);
  344. begin
  345.     CMCut(Msg);
  346. end;
  347.  
  348. procedure TUCWin.IDBut2(var Msg:TMessage);
  349. begin
  350.     CMCopy(Msg);
  351. end;
  352.  
  353. procedure TUCWin.IDBut3(var Msg:TMessage);
  354. begin
  355.     CMPaste(Msg);
  356. end;
  357.  
  358. procedure TUCWin.IDBut4(var Msg:TMessage);
  359. begin
  360.     CMDelete(Msg);
  361. end;
  362.  
  363. procedure TUCWin.IDBut5(var Msg:TMessage);
  364. begin
  365.     CMClipClear(Msg);
  366. end;
  367.  
  368. procedure TUCWin.IDBut6(var Msg:TMessage);
  369. var
  370.   WR,CR,CW:TRect;
  371.     X,Y,cKids:Integer;
  372.   Res:LongInt;
  373.   Rows,Cols:Integer;
  374.   procedure DoChildren(Child:PUCChild);far;
  375.   begin
  376.       if not(Child^.IsFlagSet(wb_MDIChild)) then Exit;
  377.     Inc(cKids);
  378.     if X+WR.Right > CR.Right then
  379.         begin
  380.       X := 0;
  381.       Y := Y+WR.Bottom;
  382.       Inc(Rows);
  383.       end;
  384.       SetWindowPos(Child^.hWindow,0,X,Y,WR.Right,WR.Bottom,0{swp_NoZOrder});
  385.     Inc(X,WR.Right);
  386.     if Rows = 1 then Inc(Cols);
  387.   end;
  388. begin
  389.   if IsZoomed(HWindow) then
  390.       ShowWindow(HWindow,sw_Normal);
  391.   ClientWnd^.Scroller^.Scrollto(0,0);  {restore scroller}
  392.   Res := SendMessage(ClientWnd^.HWindow,wm_MDIGetActive,0,0);
  393.   if LongRec(Res).Hi = 1 then     {unzoom child if necessary}
  394.       ShowWindow(LongRec(Res).Lo,sw_Normal);
  395.   CopyRect(WR,ThumbRect);         {compute child window:start with size of thumbnail}
  396.   X:=0;Y:=0;Rows:=1;Cols:= 0;
  397.  
  398.   AdjustWindowRect(WR,PWindow(ChildList)^.Attr.Style,False);   {add pixels for frame,captions,etc}
  399.   WR.Right:=WR.Right+2*GetSystemMetrics(sm_CXFrame);
  400.   WR.Right:=LongMax(WR.Right,GetSystemMetrics(SM_CXMin));
  401.   WR.Bottom:=WR.Bottom+GetSystemMetrics(sm_CYCaption)+
  402.         2*GetSystemMetrics(sm_CYFrame);
  403.  
  404.   SetRectEmpty(CR);       {compute size of client window using grid and child size}
  405.   CR.Right := Grid.X*WR.Right;
  406.   CR.Bottom := Grid.Y*WR.Bottom;
  407.   AdjustWindowRect(CR,GetWindowLong(HWindow,GWL_Style),True);
  408.   CR.Right:=(CR.Right-CR.Left+2*GetSystemMetrics(SM_CXFrame))+1;
  409.   CR.Bottom :=CR.Bottom-CR.TOP+GetSystemMetrics(SM_CYCaption)+
  410.             2*GetSystemMetrics(SM_CYFrame)-1;
  411.   SetWindowPos(HWindow,0,0,0,CR.Right,CR.Bottom,swp_NoMove + swp_DrawFrame); {resize parent}
  412.     ForEach(@DoChildren);
  413.   ClientWnd^.Scroller^.SetUnits(WR.Right,WR.Bottom);
  414.   ClientWnd^.Scroller^.SetRange(Cols,Rows);
  415.   ClientWnd^.Scroller^.XPage := 1;
  416.   ClientWnd^.Scroller^.YPage := 1;
  417. end;
  418.  
  419. procedure TUCWin.ODButtonD(var Msg:TMessage);
  420. begin
  421.   case Msg.wParam of
  422.         id_But1:LoadString(HInstance, 1, Help,50);
  423.     id_But2:LoadString(HInstance, 2, Help,50);
  424.     id_But3:LoadString(HInstance, 3, Help,50);
  425.     id_But4:LoadString(HInstance, 4, Help,50);
  426.     id_But5:LoadString(HInstance, 5, Help,50);
  427.     id_But6:LoadString(HInstance, 6, Help,50);
  428.     else StrCopy(Help,'n.a.');
  429.     end;
  430.     DispInfo;
  431. end;
  432.  
  433. procedure TUCWin.ODButtonU(var Msg:TMessage);
  434. begin
  435.     StrCopy(Help,'');
  436.     DispInfo;
  437. end;
  438.  
  439. procedure TUCWin.RetitleKids;
  440. var
  441.   Kids:Array[0..5] of Char;
  442.   Title:Array[0..25] of Char;
  443.   Buf:Array[0..5] of Char;
  444.   pKids : PChar;
  445.   cKids:Word;
  446.   procedure DoChildren(Child:PUCChild);far;
  447.   begin
  448.       if not(Child^.IsFlagSet(wb_MDIChild)) then Exit;
  449.     Inc(cKids);
  450.       Str(cKids,Kids);
  451.     Child^.Co^.GetFormats(Buf);
  452.       wvsprintf(Title,'C:%s',pKids);
  453.     StrCat(Title,Buf);
  454.     SetWindowText(Child^.HWindow,Title);
  455.   end;
  456. begin
  457.     cKids := 0;
  458.   pKids := Kids;
  459.     ForEach(@DoChildren);
  460.   IF cKids>0 then
  461.       begin
  462.     ModifyMenu(Attr.Menu,cm_EditCopy,mf_ByCommand+mf_String+mf_Enabled,
  463.            cm_EditCopy,'&Copy    Ctrl+Ins');
  464.     ModifyMenu(Attr.Menu,cm_EditDelete,mf_ByCommand+mf_String+mf_Enabled,
  465.            cm_EditDelete,'&Delete    Ctrl+Del');
  466.     ModifyMenu(Attr.Menu,cm_EditCut,mf_ByCommand+mf_String+mf_Enabled,
  467.            cm_EditCut,'Cu&t    Shift+Del');
  468.     ModifyMenu(Attr.Menu,cm_CascadeChildren,mf_ByCommand+mf_String+mf_Enabled,
  469.            cm_CascadeChildren,'&Cascade');
  470.     ModifyMenu(Attr.Menu,cm_TileChildren,mf_ByCommand+mf_String+mf_Enabled,
  471.            cm_TileChildren,'&Tile');
  472.     ModifyMenu(Attr.Menu,cm_ArrangeIcons,mf_ByCommand+mf_String+mf_Enabled,
  473.            cm_ArrangeIcons,'&Arrange &Icons');
  474.     ModifyMenu(Attr.Menu,cm_CloseChildren,mf_ByCommand+mf_String+mf_Enabled,
  475.            cm_CloseChildren,'Close &All');
  476.     ModifyMenu(Attr.Menu,cm_IconAll,mf_ByCommand+mf_String+mf_Enabled,
  477.            cm_IconAll,'Iconize All');
  478.     ModifyMenu(Attr.Menu,cm_RestoreAll,mf_ByCommand+mf_String+mf_Enabled,
  479.            cm_RestoreAll,'Restore All');
  480.     end
  481.     else
  482.       begin
  483.     ModifyMenu(Attr.Menu,cm_EditCopy,mf_ByCommand+mf_String+mf_Grayed,
  484.            cm_EditCopy,'&Copy    Ctrl+Ins');
  485.     ModifyMenu(Attr.Menu,cm_EditDelete,mf_ByCommand+mf_String+mf_Grayed,
  486.            cm_EditDelete,'&Delete    Ctrl+Del');
  487.     ModifyMenu(Attr.Menu,cm_EditCut,mf_ByCommand+mf_String+mf_Grayed,
  488.            cm_EditCut,'Cu&t    Shift+Del');
  489.     ModifyMenu(Attr.Menu,cm_CascadeChildren,mf_ByCommand+mf_String+mf_Grayed,
  490.            cm_CascadeChildren,'&Cascade');
  491.     ModifyMenu(Attr.Menu,cm_TileChildren,mf_ByCommand+mf_String+mf_Grayed,
  492.            cm_TileChildren,'&Tile');
  493.     ModifyMenu(Attr.Menu,cm_ArrangeIcons,mf_ByCommand+mf_String+mf_Grayed,
  494.            cm_ArrangeIcons,'&Arrange &Icons');
  495.     ModifyMenu(Attr.Menu,cm_CloseChildren,mf_ByCommand+mf_String+mf_Grayed,
  496.            cm_CloseChildren,'Close &All');
  497.     ModifyMenu(Attr.Menu,cm_IconAll,mf_ByCommand+mf_String+mf_Grayed,
  498.            cm_IconAll,'Iconize All');
  499.     ModifyMenu(Attr.Menu,cm_RestoreAll,mf_ByCommand+mf_String+mf_Grayed,
  500.            cm_RestoreAll,'Restore All');
  501.     end;
  502.   DrawMenuBar(HWindow);
  503. end;
  504.  
  505. procedure TUCWin.CMCut(var Msg:TMessage);
  506. var
  507.     TopWin:HWnd;
  508. begin
  509.     TopWin := GetTopWindow(ClientWnd^.HWindow);
  510.   if TopWin > 0 then SendMessage(TopWin,WM_User+UM_Copy,0,0);
  511.   if TopWin > 0 then SendMessage(TopWin,WM_User+UM_Delete,0,0);
  512. end;
  513.  
  514. procedure TUCWin.CMCopy(var Msg:TMessage);
  515. var
  516.     TopWin:HWnd;
  517. begin
  518.     TopWin :=GetTopwindow(ClientWnd^.HWindow);
  519.   if Topwin > 0 then SendMessage(Topwin,WM_User+UM_Copy,0,0);
  520. end;
  521.  
  522. procedure TUCWin.CMPaste(var Msg:TMessage);
  523. var
  524.   W:PUCChild;
  525. begin
  526.   W := nil;
  527.   if CountClipboardFormats = 0 then exit;
  528.   W :=PUCChild(Application^.MakeWindow(New(PUCChild,Init(@Self,' ',ThumbRect ))));
  529.   ShowWindow(W^.HWindow,SW_ShowNoActivate);
  530.   EnableWindow(W^.HWindow,True);
  531.   if W <> nil then
  532.         If W^.CO = nil then
  533.             W^.CloseWindow
  534.         else
  535.            RetitleKids;
  536. end;
  537.  
  538. procedure TUCWin.CMDelete(var Msg:TMessage);
  539. var TopWin:HWnd;
  540. begin
  541.     TopWin:=GetTopWindow(ClientWnd^.HWindow);
  542.   if TopWin > 0 then
  543.       SendMessage(TopWin,WM_User+UM_Delete,0,0);
  544. end;
  545.  
  546. procedure TUCWin.CMAutoPaste(var Msg:TMessage);
  547. begin
  548.     if not IsAutoPaste then
  549.       begin
  550.     IsAutoPaste := True;
  551.     NextViewer := SetClipboardViewer(HWindow);
  552.     ModifyMenu(Attr.Menu,cm_AutoPaste,mf_ByCommand+mf_String,
  553.            cm_AutoPaste,'Stop AutoPaste');
  554.     end
  555.     else
  556.         begin
  557.         ChangeClipboardChain(HWindow,NextViewer);
  558.     IsAutoPaste := false;
  559.     NextViewer := 0;
  560.     ModifyMenu(Attr.Menu,cm_AutoPaste,mf_ByCommand+mf_String,
  561.            cm_AutoPaste,'Start AutoPaste');
  562.     end;
  563.   DrawMenuBar(HWindow);
  564.   DispInfo;
  565. end;
  566.  
  567. procedure TUCWin.CMClipClear(var Msg:TMessage);
  568. begin
  569.     OpenClipboard(hWindow);
  570.   EmptyClipboard;
  571.   Closeclipboard;
  572. end;
  573.  
  574. procedure TUCWin.CMRunCB(var Msg:TMessage);
  575. begin
  576.     WinExec('clipbrd.exe',sw_ShowNormal);
  577. end;
  578.  
  579. procedure TUCWin.CMConfigure(var Msg:TMessage);
  580. var
  581.     TheDialog:PDialog;
  582.     TfB :Record
  583.       RB1,RB2:Bool;
  584.     EC1,EC2,EC3:Array[0..4] of Char;
  585.   end;
  586.   RBut1,RBut2:PRadioButton;
  587.   ECtl1,ECtl2,Ectl3:PEdit;
  588.   FontBut:PButton;
  589.   TNS,Error:Integer;
  590. begin
  591.     TheDialog :=New(PDialog,Init(@Self,'UC_Dlg1'));
  592.   New(RBut1,InitResource(TheDialog,id_D1RB1));
  593.   New(RBut2,InitResource(TheDialog,id_D1RB2));
  594.   New(ECtl1,InitResource(TheDialog,id_D1EC1,5));
  595.   New(ECtl2,InitResource(TheDialog,id_D1EC2,5));
  596.     New(ECtl3,InitResource(TheDialog,id_D1EC3,5));
  597.   TfB.RB1 := False;TfB.RB2 := False;
  598.   Str(ThumbRect.Right,TfB.EC1);
  599.   Str(Grid.X,TfB.EC2);
  600.   Str(Grid.Y,TfB.EC3);
  601.   if IsAutoPaste then TfB.RB1 := True else TfB.RB2 := True;
  602.   TheDialog^.TransferBuffer := @TfB;
  603.   Application^.ExecDialog(TheDialog);
  604.   If TfB.RB1 then
  605.     WritePrivateProfileString(AppName,'AutoPaste','1',IniFile)
  606.   else
  607.     WritePrivateProfileString(Appname,'AutoPaste','0',IniFile);
  608.   WritePrivateProfileString(Appname,'ThumbNailSize',TfB.EC1,IniFile);
  609.   Val(TfB.EC1,TNS,Error);
  610.   SetRect(ThumbRect,0,0,TNS,TNS);
  611.     Val(TfB.EC2,Grid.X,Error);
  612.   WritePrivateProfileString(Appname,'Across',TfB.EC2,IniFile);
  613.     Val(TfB.EC3,Grid.Y,Error);
  614.   WritePrivateProfileString(Appname,'Down',TfB.EC3,IniFile);
  615.   IDBut6(Msg);
  616. end;
  617.  
  618. procedure TUCWin.CMIconAll(var Msg:TMessage);
  619.   procedure ShrinkKids(Child:PWindowsObject);far;
  620.   begin
  621.       If not(Child^.IsFlagSet(wb_MDIChild)) then Exit;
  622.     If Child^.HWindow = 0 then EXIT;
  623.     ShowWindow(Child^.HWindow,sw_Minimize);
  624.         end;
  625. begin
  626.     ForEach(@ShrinkKids);
  627. end;
  628.  
  629. procedure TUCWin.CMRestoreAll(var Msg:TMessage);
  630.   procedure RestoreKids(Child:PWindowsObject);far;
  631.   begin
  632.       If not(Child^.IsFlagSet(wb_MDIChild)) then Exit;
  633.     If Child^.HWindow = 0 then EXIT;
  634.     ShowWindow(Child^.HWindow,sw_Normal);
  635.         end;
  636. begin
  637.     ForEach(@RestoreKids);
  638. end;
  639.  
  640. procedure TUCWin.WMChangeCBChain(var Msg:TMessage);
  641. begin
  642.     if Msg.wParam = NextViewer then
  643.       begin
  644.     NextViewer := Msg.lParamLo;
  645.     SendMessage(NextViewer,wm_ChangeCBChain,Msg.wParam,Msg.lParam);
  646.     end;
  647. end;
  648.  
  649. procedure    TUCWin.WMSysCommand(var Msg:TMessage);
  650. begin
  651.     case Msg.Wparam of
  652.         idm_About:
  653.              Application^.ExecDialog(New(PUCAbout,Init(@Self,'UC_About')));
  654.     idm_ClipBoard:
  655.         WinExec('clipbrd.exe',sw_ShowNormal);
  656.        else
  657.            DefWndProc(Msg);
  658.        end;
  659. end;
  660.  
  661. procedure TUCWin.WMDrawClipBoard(var Msg:TMessage);
  662. var
  663.     ClipOwner :HWnd;
  664.   IsItOurs:Bool;
  665.  
  666.   procedure IsKid(Child:PWindowsObject);far;
  667.   begin
  668.       if Child^.HWindow = ClipOwner then IsItOurs := True;
  669.   end;
  670.  
  671. begin
  672.   ClipOwner := GetClipboardOwner; IsItOurs := False;
  673.   ForEach(@IsKid);
  674.   if not IsItOurs then
  675.       CMPaste(Msg);
  676.   if NextViewer <> 0 then    
  677.       SendMessage(NextViewer,wm_DrawClipboard,Msg.wParam,Msg.lParam);
  678.   IF CountClipBoardFormats>0 then
  679.       begin
  680.     ModifyMenu(Attr.Menu,cm_EditPaste,mf_ByCommand+mf_String+mf_Enabled,
  681.            cm_EditPaste,'&Paste    Shift+Ins');
  682.     ModifyMenu(Attr.Menu,cm_ClipClear,mf_ByCommand+mf_String+mf_Enabled,
  683.            cm_ClipClear,'Clea&r Clipboard');
  684.     end
  685.     else
  686.       begin
  687.     ModifyMenu(Attr.Menu,cm_EditPaste,mf_ByCommand+mf_String+mf_Grayed,
  688.            cm_EditPaste,'&Paste    Shift+Ins');
  689.     ModifyMenu(Attr.Menu,cm_ClipClear,mf_ByCommand+mf_String+mf_Grayed,
  690.            cm_ClipClear,'Clea&r Clipboard');
  691.     end;
  692.   DrawMenuBar(HWindow);
  693. end;
  694.  
  695. procedure TUCWin.WMTimer(var Msg:TMessage);
  696. var
  697.     GlobMem:LongInt;
  698.   Title:Array[0..25] of Char;
  699. begin
  700.     GlobMem := GetFreeSpace(0);
  701.   GlobMem := GlobMem div 1024 div 1024;
  702.   wvsprintf(Title,'UltraClip: %li MB Free',GlobMem);
  703.   SetWindowText(HWindow,Title);
  704. end;
  705.  
  706. procedure TUCWin.WMPaletteChanged(var Msg:TMessage);
  707. var
  708.     IsChild:Boolean;
  709.   Ret:LongRec;
  710.  
  711.   procedure IsKid(Child:PWindowsObject);far;
  712.   begin
  713.     if Child^.HWindow = Msg.wParam
  714.         then IsChild := True;
  715.   end;
  716.  
  717. begin       {only respond to changes from other apps}
  718.     IsChild := False;
  719.   ForEach(@IsKid);
  720.     if not IsChild then
  721.       InvalidateRect(HWindow,nil,false);
  722. end;
  723.  
  724. procedure TUCWin.WMQueryNewPalette(var Msg:TMessage);
  725. begin
  726.   InvalidateRect(HWindow,nil,false);
  727. end;
  728.  
  729. procedure TUCWin.WMSize(var Msg:TMessage);
  730. var
  731.     Indx:Integer;
  732.   CR:TRect;
  733. begin
  734.     GetClientRect(HWindow,CR);
  735.     if (ClientWnd <> nil) and (ClientWnd^.HWindow <> 0) then
  736.         MoveWindow(ClientWnd^.HWindow,0,33,Msg.lParamLo,Msg.LParamHi-33,True);
  737.   for Indx := 1 to 6 do
  738.       begin
  739.     if (BN[Indx] <> nil) and (BN[Indx]^.HWindow <> 0) then
  740.         MoveWindow(BN[Indx]^.HWindow,(Indx-1)*33,0,32,32,True);
  741.     end;
  742.   If (ST1 <> nil) and (ST1^.HWindow <> 0) then
  743.       ST1^.MoveWin(210,5,Cr.Right-220,23);
  744.   CR.Bottom := 32;
  745.   InvalidateRect(HWindow,@CR,True);
  746. end;
  747.  
  748. procedure    TUCWin.WMDrawItem(var Msg:TMessage);
  749. var
  750.     PDIS : ^TDrawItemStruct;
  751. begin
  752.     PDIS := Pointer(Msg.lParam);
  753.     case PDIS^.CtlType of
  754.         odt_Button:
  755.         case PDIS^.CtlID of
  756.             id_But1..id_But6:Bn[PDIS^.CtlID-Pred(id_But1)]^.DrawItem(Msg);
  757.         end;
  758.     end;
  759. end;
  760.  
  761. procedure TUCWin.WMNCRButtonUp(var Msg:TMessage);
  762. begin
  763.     CMConfigure(Msg);
  764. end;
  765.  
  766. procedure TUCWin.UMChildExit(var Msg:TMessage);
  767. begin
  768.   RetitleKids;
  769.   DispInfo;
  770. end;
  771.  
  772. procedure TUCWin.UMChildFocus(var Msg:TMessage);
  773. begin
  774.     DispInfo;
  775. end;
  776.  
  777. procedure TUCWin.UMRButtonDown(var Msg:TMessage);
  778. begin
  779.     if Msg.wParam <> id_ST1 then EXIT;
  780.     CMAutoPaste(Msg);
  781.     DispInfo;
  782. end;
  783. {***********************  TUCChild  ***********************************}
  784. constructor TUCChild.Init(AParent:PWindowsObject;ATitle:PChar;SRx:TRect);
  785. var Stat:Word;
  786. begin
  787.     TWindow.Init(AParent,ATitle);
  788.   ThumbRect:=SRx;
  789.   Attr.Style := Attr.Style or ws_Disabled;
  790. end;
  791.  
  792. destructor TUCChild.Done;
  793. begin
  794.     if CO <> nil then Dispose(CO,Done);
  795.   if Parent^.HWindow <> 0 then    
  796.       PostMessage(Parent^.HWindow,wm_User+um_ChildExit,0,0);
  797.   TWindow.Done;
  798. end;
  799.  
  800. procedure TUCChild.SetupWindow;
  801. var
  802.     CR:TRect;
  803.   tb:TBitmap;
  804.   Stat:Word;
  805.   WR:TREct;
  806. begin
  807.     TWindow.SetupWindow;
  808.   GetClientRect(PMDIWindow(Parent)^.ClientWnd^.HWindow,CR);
  809.     InflateRect(CR, -(CR.Right div 20), -(CR.Bottom div 20));
  810.   SetWindowPos(HWindow,HWND_BOTTOM,0,0,CR.Right,CR.Bottom,swp_NoActivate );
  811.     CO :=New(PClipObj,Init(HWindow,Stat,ThumbRect));
  812.   if Stat <> st_OK then
  813.     MessageBox(Parent^.HWindow,'Error Pasting from Clipboard ',
  814.         'UltraClip Alert',mb_systemmodal or mb_iconExclamation)
  815.   else
  816.       IsActive := True;
  817.   CopyRect(WR,ThumbRect);
  818.   AdjustWindowRect(WR,Attr.Style,False);
  819.   SetWindowPos(hWindow,0,0,0,WR.Right+2*GetSystemMetrics(sm_CXFrame),
  820.         WR.Bottom+GetSystemMetrics(sm_CYCaption)+2*GetSystemMetrics(sm_CYFrame),
  821.         swp_NoZOrder or swp_NoMove);
  822. end;
  823.  
  824. procedure TUCChild.Paint(PaintDC:HDC;var PaintInfo:TPaintStruct);
  825. var
  826.     oc:HCursor;
  827. begin
  828.     if CO = nil then Exit; 
  829.   oc := SetCursor(LoadCursor(0,IDC_WAIT));
  830.   if IsActive then    
  831.       CO^.RenderSelf(PaintDC,HWindow,IsZoomed(HWindow))
  832.      else
  833.         CO^.RedrawSelf(PaintDC,HWindow,IsZoomed(HWindow));
  834.   SetCursor(oc);
  835. end;
  836.  
  837. function TUCChild.GetClassName;
  838. begin
  839.   GetClassName := ChdName;
  840. end;
  841.  
  842. procedure TUCChild.GetWindowClass(VAR AWndClass:TWndClass);
  843. begin
  844.   TWindow.GetWindowClass(AWndClass);
  845.   AWndClass.hIcon := LoadIcon(HInstance, 'UC_IconC');
  846.   AWndClass.hBrBackground := GetStockObject(ltGray_Brush);
  847. end;
  848.  
  849. procedure TUCChild.WMNCRButtonUp(var Msg:TMessage);
  850. begin
  851.     SetFocus(HWindow);
  852.   InvalidateRect(HWindow,nil,false);
  853.     PostMessage(HWindow,wm_User+um_Copy,Msg.wParam,Msg.lParam);
  854. end;
  855.  
  856. procedure TUCChild.WMPaletteChanged(var Msg:TMessage);
  857. var
  858.     DC:HDC;
  859. begin
  860.     if Msg.wParam <> HWindow then
  861.       if IsActive then
  862.           begin
  863.         GetDC(HWindow);
  864.         CO^.RenderSelf(DC,HWindow,IsZoomed(HWindow));
  865.         ReleaseDC(HWindow,DC);
  866.         end;
  867. end;
  868.  
  869. procedure TUCChild.WMMDIActivate(var Msg:TMessage);
  870. var
  871.     DC:HDC;
  872. begin
  873.     IsActive := Bool(Msg.wParam);
  874.   if IsActive then
  875.       begin
  876.     SetFocus(HWindow);
  877.         InvalidateRect(HWindow,nil,True);
  878.         PostMessage(Parent^.HWindow,wm_User+um_ChildFocus,0,LongInt(@Self));
  879.     end;
  880. end;
  881.  
  882. procedure TUCChild.WMSize(var Msg:TMessage);
  883. begin
  884.     if (Msg.wParam <> size_MaxHide) and (Msg.wParam <> size_MaxShow)
  885.       and IsActive then
  886.             PostMessage(Parent^.HWindow,wm_User+um_ChildFocus,0,LongInt(@Self));
  887.   DefWndProc(Msg);
  888. end;
  889.  
  890. procedure TUCChild.WMRButtonUp(var Msg:TMessage);
  891. var
  892.     Dlg2:PUCDlg2;
  893.   Ctrl:PControl;
  894.   Indx:Integer;
  895.   Clip:PClipItem;
  896.   Clips:PCollection;
  897.   Ret:Integer;
  898.   TfB:TfR;
  899. begin          {dlg with listbox of available formats}
  900.     TfB.Strings :=New(PStrCollectionNS,Init(10,10));
  901.   TfB.Indexes:=nil;
  902.     Dlg2 := New(PUCDlg2,Init(@Self,'UC_Dlg2'));
  903.   Ctrl:=New(PListBox,InitResource(Dlg2,id_D2LB1));
  904.   Clips:=CO^.GetClips;
  905.   for Indx := 0 to (Clips^.Count-1) do
  906.       begin
  907.     Clip:=Clips^.At(Indx);
  908.     TfB.Strings^.Insert(StrNew(Clip^.CName));
  909.     end;
  910.   Dlg2^.TransferBuffer := @TfB;
  911.     Ret := Application^.ExecDialog(Dlg2);
  912.   if (Ret = id_OK) and (TfB.Indexes <> nil) then
  913.       begin
  914.       CO^.CopyClipS(HWindow,TfB.Indexes);
  915.       FreeMultiSel(TfB.Indexes);
  916.     TfB.Indexes := nil;
  917.     end;
  918.   Dispose(TfB.Strings,Done);
  919. end;
  920.  
  921. procedure TUCChild.WMLButtonDown(var Msg:TMessage);
  922. var
  923.     Dlg2:PUCDlg2;
  924.   Buf:Array[0..2] of Char;
  925. begin            {toggle display format if graphics & text}
  926.     StrCopy(Buf,'');
  927.     CO^.ToggleIsPrefText;
  928.   CO^.GetFormats(Buf);
  929.   if Buf[0] = '*' then
  930.       InvalidateRect(HWindow,nil,True);
  931. end;
  932.  
  933. procedure TUCChild.UMGetSelf(var Msg:TMessage);
  934. begin         {use getobjptr() instead}
  935.     Msg.Result := LongInt(@Self);
  936. end;
  937.  
  938. procedure TUCChild.UMCopy(var Msg:TMessage);
  939. var
  940.     TfB:TfR;
  941. begin     {cc_CopyAll a local convention;Strings pointer not used}
  942.     TfB.Strings :=nil;
  943.   TfB.Indexes:=AllocMultiSel(cc_CopyAll);
  944.     if CO <> nil then
  945.         CO^.CopyClipS(HWindow,TfB.Indexes);
  946.   FreeMultiSel(TfB.Indexes);
  947. end;
  948.  
  949. procedure TUCChild.UMDelete(var Msg:TMessage);
  950. begin
  951.     CloseWindow;
  952. end;
  953.  
  954. {************************  TUCClient  *******************************}
  955. constructor TUCClient.Init(AParent:PMDIWindow);
  956. begin
  957.     TMDIClient.Init(AParent);
  958.   Scroller :=New(PScroller,Init(@self,125,125,200,200));
  959.   Scroller^.XPage := 1;
  960.   Scroller^.YPage := 1;
  961. end;
  962.  
  963. procedure TUCClient.WMSize(var Msg:TMessage);
  964. begin
  965.     DefWndProc(Msg);
  966. end;
  967. {************************   TUCBtn  *********************************}
  968. constructor    TUCBtn.Init(AParent:PWindowsObject; AnID:Integer;ATitle:PChar;
  969.       X1,Y1,W1,H1:Integer;IsDefault:Boolean;BMP:PChar;AGroup:PGroupBox);
  970. begin
  971.     TODButton.Init(AParent,AnID,ATitle,X1,Y1,W1,H1,IsDefault,BMP,AGroup);
  972.   SetFlags(wb_MDIChild,False);
  973.   DefaultProc := @DefWindowProc;
  974. end;
  975.  
  976. procedure TUCBtn.WMRButtonDown(var Msg:TMessage);
  977. begin
  978.   SendMessage(Parent^.HWindow,wm_User+um_ButtonD,GetID,0);
  979. end;
  980.  
  981. procedure TUCBtn.WMRButtonUp(var Msg:TMessage);
  982. begin
  983.   SendMessage(Parent^.HWindow,wm_User+um_ButtonU,GetID,0);
  984. end;
  985. {***********************  TUCStatic  ********************************}
  986. constructor TUCStatic.Init(AParent:PWindowsObject;AnID:Integer; ATitle:PChar;
  987.       NewX,NewY,NewW,NewH:Integer; NewState,NewStyle:Integer);
  988. begin
  989.     TSText.Init(AParent,AnID, ATitle,NewX,NewY,NewW,NewH,NewState,NewStyle);
  990.   SetFlags(wb_MDIChild,False);
  991.   DefaultProc := @DefWindowProc;
  992. end;
  993.  
  994. procedure TUCStatic.WMRButtonDown(var Msg:TMessage);
  995. begin
  996.   SendMessage(Parent^.HWindow,wm_User+wm_RButtonDown,GetID,0);
  997. end;
  998. {**********************  TUCAbout  ********************************}
  999. procedure TUCAbout.WMCTLCOLOR(var Msg: TMessage);
  1000. begin
  1001.   case Msg.LParamHi of
  1002.     ctlColor_Static,ctlcolor_Dlg:
  1003.       begin
  1004.       SetBkMode(Msg.WParam, Transparent);
  1005.       Msg.Result := GetStockObject(ltGray_Brush);
  1006.       end;
  1007.   else
  1008.     DefWndProc(Msg);
  1009.   end;
  1010. end;
  1011. {************************* TUCDlg2  *********************************}
  1012. constructor TUCDlg2.Init(AParent: PWindowsObject; AName: PChar);
  1013. begin
  1014.     TDialog.Init(AParent,AName);
  1015. end;
  1016.  
  1017. procedure TUCDlg2.SetupWindow;
  1018. begin
  1019.     TDialog.SetupWindow;
  1020. end;
  1021. {***********************  TStrCollectionNS  ****************************}
  1022. procedure TStrCollectionNS.Insert(Item:Pointer);
  1023. begin
  1024.     AtInsert(Count,Item);
  1025. end;
  1026. {***********************   Main Line  **********************************}
  1027. var
  1028.     TheApp: TUCApp;
  1029. begin
  1030.   TheApp.Init(AppName);
  1031.   TheApp.Run;
  1032.   TheApp.Done;
  1033. end.
  1034.